﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace GTAuto.Site.BackEnd.AppCode.Helpers.Html
{
    public class NewAdsPager
    {

        private ViewContext viewContext;
        private readonly int pageSize;
        private readonly int currentPage;
        private readonly int totalItemCount;
        private readonly RouteValueDictionary linkWithoutPageValuesDictionary;

        public NewAdsPager(ViewContext viewContext, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary)
        {
            this.viewContext = viewContext;
            this.pageSize = pageSize;
            this.currentPage = currentPage;
            this.totalItemCount = totalItemCount;
            this.linkWithoutPageValuesDictionary = valuesDictionary;
        }

        public string RenderHtml()
        {
            int pageCount = (int)Math.Ceiling(this.totalItemCount / (double)this.pageSize);
            int nrOfPagesToDisplay = 10;

            var sb = new StringBuilder();

            // Previous
            if (this.currentPage > 1)
            {
                sb.Append(GeneratePageLink("&lt;", this.currentPage - 1));
            }
            else
            {
                sb.Append("<span class=\"disabled\">&lt;</span>");
            }

            int start = 1;
            int end = pageCount;

            if (pageCount > nrOfPagesToDisplay)
            {
                int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1;
                int below = (this.currentPage - middle);
                int above = (this.currentPage + middle);

                if (below < 4)
                {
                    above = nrOfPagesToDisplay;
                    below = 1;
                }
                else if (above > (pageCount - 4))
                {
                    above = pageCount;
                    below = (pageCount - nrOfPagesToDisplay);
                }

                start = below;
                end = above;
            }

            if (start > 3)
            {
                sb.Append(GeneratePageLink("1", 1));
                sb.Append(GeneratePageLink("2", 2));
                sb.Append("...");
            }
            for (int i = start; i <= end; i++)
            {
                if (i == this.currentPage)
                {
                    sb.AppendFormat("<span class=\"current\">{0}</span>", i);
                }
                else
                {
                    sb.Append(GeneratePageLink(i.ToString(), i));
                }
            }
            if (end < (pageCount - 3))
            {
                sb.Append("...");
                sb.Append(GeneratePageLink((pageCount - 1).ToString(), pageCount - 1));
                sb.Append(GeneratePageLink(pageCount.ToString(), pageCount));
            }

            // Next
            if (this.currentPage < pageCount)
            {
                sb.Append(GeneratePageLink("&gt;", (this.currentPage + 1)));
            }
            else
            {
                sb.Append("<span class=\"disabled\">&gt;</span>");
            }

            string test = sb.ToString();
            return test;
        }

        private string GeneratePageLink(string linkText, int pageNumber)
        {
            // Добавить номер страницы в параметры
            var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary);
            //pageLinkValueDictionary.Add("page", pageNumber);
            var virtualPathData = RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary);

            if (virtualPathData != null)
            {
                string link = virtualPathData.VirtualPath;

                string[] strings = link.Split('/');

                if (strings.Count() == 4)
                {
                    link = strings[0] + "/" + strings[1] + "/" + strings[2];
                }


                if (linkText == "&gt;" || linkText == "&lt;")
                {
                    if (linkText == "&gt;")
                    {
                        string linkFormat = "<a href=\"/admin/Ads/NewAds/{0} \"  >&gt;</a>";
                        //string str = String.Format(linkFormat, link + "/" + pageNumber, linkText);
                        string str = String.Format(linkFormat, currentPage + 1);
                        return str;
                    }
                    else
                    {
                        string linkFormat = "<a href=\"/admin/Ads/NewAds/{0} \"  >&lt;</a>";
                        //string str = String.Format(linkFormat, link + "/" + pageNumber, linkText);
                        string str = String.Format(linkFormat, currentPage - 1);
                        return str;
                    }
                }
                else
                {
                    string linkFormat = "<a href=\"/admin/Ads/NewAds/{0} \" >{0}</a>";
                    //string str = String.Format(linkFormat, link + "/" + pageNumber, linkText);
                    string str = String.Format(linkFormat, linkText);
                    return str;
                }
            }
            else
            {
                return null;
            }
        }
    }


    public interface INewAdsPagedList<T> : IList<T>
    {
        int PageCount { get; }
        int TotalItemCount { get; }
        int PageIndex { get; }
        int PageNumber { get; }
        int PageSize { get; }
        bool HasPreviousPage { get; }
        bool HasNextPage { get; }
        bool IsFirstPage { get; }
        bool IsLastPage { get; }
    }


    public class NewAdsPagedList<T> : List<T>, INewAdsPagedList<T>
    {
        public NewAdsPagedList(IEnumerable<T> source, int index, int pageSize, int totalCount)
        {
            Initialize(source.AsQueryable(), index, pageSize, totalCount);
        }

        #region INewAdsPagedList Members

        public int PageCount { get; private set; }
        public int TotalItemCount { get; private set; }
        public int PageIndex { get; private set; }
        public int PageNumber { get { return PageIndex + 1; } }
        public int PageSize { get; private set; }
        public bool HasPreviousPage { get; private set; }
        public bool HasNextPage { get; private set; }
        public bool IsFirstPage { get; private set; }
        public bool IsLastPage { get; private set; }

        #endregion

        protected void Initialize(IEnumerable<T> source, int index, int pageSize, int totalCount)
        {
            //### argument checking
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("PageIndex cannot be below 0.");
            }
            if (pageSize < 1)
            {
                throw new ArgumentOutOfRangeException("PageSize cannot be less than 1.");
            }

            //### set source to blank list if source is null to prevent exceptions
            if (source == null)
            {
                source = new List<T>();
            }

            PageSize = pageSize;
            PageIndex = index;
            TotalItemCount = totalCount;
            if (TotalItemCount > 0)
            {
                PageCount = (int)Math.Ceiling(TotalItemCount / (double)PageSize);
            }
            else
            {
                PageCount = 0;
            }
            HasPreviousPage = (PageIndex > 0);
            HasNextPage = (PageIndex < (PageCount - 1));
            IsFirstPage = (PageIndex <= 0);
            IsLastPage = (PageIndex >= (PageCount - 1));

            //### add items to internal list
            AddRange(source);
        }
    }

    public static class NewAdsPagingExtensions
    {
        #region NewAdsPagingExtensions extensions


        public static MvcHtmlString NwAdsPager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount)
        {

            var valuesDictionary = htmlHelper.ViewContext.Controller.ControllerContext.RouteData.Values;
            var pager = new NewAdsPager(htmlHelper.ViewContext, pageSize, currentPage, totalItemCount, valuesDictionary);

            string str = pager.RenderHtml();
            MvcHtmlString htmlString = new MvcHtmlString(str);

            return htmlString;
        }
        #endregion

        #region IEnumerable<T> extensions

        public static INewAdsPagedList<T> ToPagedList<T>(this IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
        {
            return new NewAdsPagedList<T>(source, pageIndex, pageSize, totalCount);
        }

        #endregion

    }

}